package cn.org.xuanzp.examples.v2.client.one;

import cn.org.xuanzp.common.command.Command;
import cn.org.xuanzp.common.command.impl.LoginCommand;
import cn.org.xuanzp.common.command.impl.LoginoutCommand;
import cn.org.xuanzp.common.utils.CommandUtils;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.util.Map;
import java.util.Scanner;

/**
 * @Classname Client
 * @Description TODO
 * @Version 1.0.0
 * @Date 2024/9/24 22:48
 * @Created by xuanzp
 */
public class Client {
    public static String toId = "qwer";
    public static ChannelHandlerContext ctx;

    private String host;// 当前netty客户端连接的主机地址
    private int port;// 当前netty客户端连接的端口
    private Channel channel;
    private EventLoopGroup mainGroup;
    public Client(String host, int port) {
        this.host = host;
        this.port = port;
        this.mainGroup = new NioEventLoopGroup();
    }


    public Channel getChannel() {
        return channel;
    }

    // 启动当前netty服务器的操作
    public void start() throws Exception {
        Bootstrap b = new Bootstrap(); // (1)
        b.group(mainGroup); // (2)
        b.channel(NioSocketChannel.class); // (3)
        //b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
        //NettyFtpClientHandler nettyClientHandler = new NettyFtpClientHandler();
        b.handler(new NettyClientInitializer());
		/*
		b.handler(new ChannelInitializer<SocketChannel>() {
			@Override
			public void initChannel(SocketChannel ch) throws Exception {
				ch.pipeline().addLast(nettyClientHandler).addLast(new StringEncoder())// 添加传输数据的转码器
						.addLast(new StringDecoder());// 添加接收数据的解码器
			}
		});*/

        // Start the client.
        ChannelFuture future = b.connect(host, port).sync(); // (5)
        // 添加监听器，用于判断是否连接成功或者连接失败
        future.addListener(new ChannelFutureListener() {

            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("连接服务器成功");

                } else {
                    System.out.println("连接服务器失败");
                    future.cause().printStackTrace();
                    mainGroup.shutdownGracefully(); // 关闭线程组
                }

            }
        });
        this.channel = future.channel();

    }

    // 创建向服务器发送消息的方法
    public void send(String message) {
        Channel channel = this.getChannel();
        channel.writeAndFlush(message);
    }

    public void send(Object obj) {
        Channel channel = this.getChannel();
        System.out.println("channel:::"+channel.isActive()+" "+channel.isOpen());

//        channel.writeAndFlush(Unpooled.buffer().writeBytes(JSONUtil.toJsonStr(obj).getBytes()));

        ChannelFuture channelFuture = channel.writeAndFlush(obj);
        ChannelFuture channelFuture1 = Client.ctx.writeAndFlush(obj);
        System.out.println(channelFuture.isSuccess()+" "+channelFuture1.isSuccess());
    }

    boolean isRun = true;

    // 客户端的被动关闭操作,由服务器发起操作
    public void close() {
        isRun = false;
        mainGroup.shutdownGracefully();// 关闭当前的线程组
    }

    // 客户端的主动关闭操作
    public void closeAndSendToServer() {
        send("CLIENT CLOSED");
        mainGroup.shutdownGracefully();// 关闭当前的线程组
    }

    public Command getUserOption() {
        System.out.println("请输入指令执行操作："+this.channel.id().asLongText());
        System.out.println("请输入指令执行操作：");
        System.out.println("1.消息\n2.登出\n3.登录\n0.退出");
        Scanner clientInput = new Scanner(System.in);
        String nextLine = clientInput.nextLine();
        switch (nextLine) {
            case "1":
                return getCommand("uploadFile");//command;
            case "2":
                LoginoutCommand loginoutCommand = new LoginoutCommand();
                loginoutCommand.setUserName("admin");
                return loginoutCommand;
            case "3":
                LoginCommand loginCommand = new LoginCommand();
                loginCommand.setUserName("admin");
                loginCommand.setPassword("123456");
                return loginCommand;
            case "0":
                closeAndSendToServer();// 关闭当前的客户端
                return null;
            default:
                return null;
        }
    }

    private Command getCommand(String msg) {
        MyMessageCommand command = new MyMessageCommand() ;
        MyPayload payload = new MyPayload();
        payload.setMsg(msg);
        command.setPayload(payload);

        Map headers = command.getHeaders();
        headers.put(CommandUtils.COMMAND_HEADER_TO,Client.toId);
        return command;
    }

    // 当前客户端的操作
    public void clientOption() {
        while (isRun) {
            Command command = getUserOption();
            if (!this.getChannel().isActive() || !this.getChannel().isOpen()) {
                close();// 关闭当前的客户端
                break;
            }
            if(command!=null) {
                // 注意这个地方必须传递Object,否则出现不解析的问题
                send(command);
            }else {
                System.out.println("command is null.....");
            }

        }

    }


    public static void main(String[] args) throws Exception {
        Client client = new Client("127.0.0.1",8848);
        client.start();
        client.clientOption();
        /*Map map = new HashMap(10);

        map.put("1",1);
        map.put("3",3);
        map.put("3",3);*/

        /*MyMessageCommand command = new MyMessageCommand() ;
        MyCommandPayload payload = new MyCommandPayload();
        payload.setMsg("msg");
        command.setPayload(payload);

        Map headers = command.getHeaders();
        headers.put(CommandUtils.COMMAND_HEADER_TO,Client.toId);

        client.send(command);*/
    }
}
